package com.imooc.pan.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.imooc.pan.context.*;
import com.imooc.pan.converter.UserConverter;
import com.imooc.pan.core.response.R;
import com.imooc.pan.core.utils.IdUtil;
import com.imooc.pan.entity.RPanUser;
import com.imooc.pan.entity.RPanUserFile;
import com.imooc.pan.po.*;
import com.imooc.pan.service.IUserService;
import com.imooc.pan.service.RPanUserStorageService;
import com.imooc.pan.vo.UserInfoVO;
import com.imooc.pan.vo.UserStorageSizeVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

/**
 * 该类是用户模块的控制器实体
 */
@RestController
@RequestMapping("user")
@Api(tags = "用户模块")
public class UserController {

    @Autowired
    private IUserService iUserService;

    @Autowired
    private UserConverter userConverter;
    
    @Autowired
    private RPanUserStorageService userStorageService;
    

    @ApiOperation(
            value = "用户注册接口",
            notes = "该接口提供了用户注册的功能，实现了冥等性注册的逻辑，可以放心多并发调用",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @PostMapping("register")
    public R register(@Validated @RequestBody UserRegisterPO userRegisterPO) {
        UserRegisterContext userRegisterContext = userConverter.userRegisterPO2UserRegisterContext(userRegisterPO);
        Long userId = iUserService.register(userRegisterContext);
        return R.data(IdUtil.encrypt(userId));
    }

    @ApiOperation(
            value = "用户登录接口",
            notes = "该接口提供了用户登录的功能，成功登陆之后，会返回有时效性的accessToken供后续服务使用",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    // @LoginIgnore
    @PostMapping("login")
    public R login(@Validated @RequestBody UserLoginPO userLoginPO) {
        UserLoginContext userLoginContext = userConverter.userLoginPO2UserLoginContext(userLoginPO);
        String accessToken = iUserService.login(userLoginContext);
        return R.data(accessToken);
    }

    @ApiOperation(
            value = "用户登出接口",
            notes = "该接口提供了用户登出的功能",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @PostMapping("exit")
    public R exit() {
        iUserService.exit(StpUtil.getLoginIdAsLong());
        return R.success();
    }

    @ApiOperation(
            value = "用户忘记密码-校验用户名",
            notes = "该接口提供了用户忘记密码-校验用户名的功能",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    // @LoginIgnore
    @PostMapping("username/check")
    public R checkUsername(@Validated @RequestBody CheckUsernamePO checkUsernamePO) {
        CheckUsernameContext checkUsernameContext = userConverter.checkUsernamePO2CheckUsernameContext(checkUsernamePO);
        String question = iUserService.checkUsername(checkUsernameContext);
        return R.data(question);
    }

    @ApiOperation(
            value = "用户忘记密码-校验密保答案",
            notes = "该接口提供了用户忘记密码-校验密保答案的功能",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    // @LoginIgnore
    @PostMapping("answer/check")
    public R checkAnswer(@Validated @RequestBody CheckAnswerPO checkAnswerPO) {
        CheckAnswerContext checkAnswerContext = userConverter.checkAnswerPO2CheckAnswerContext(checkAnswerPO);
        String token = iUserService.checkAnswer(checkAnswerContext);
        return R.data(token);
    }

    @ApiOperation(
            value = "用户忘记密码-重置新密码",
            notes = "该接口提供了用户忘记密码-重置新密码的功能",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @PostMapping("password/reset")
    // @LoginIgnore
    public R resetPassword(@Validated @RequestBody ResetPasswordPO resetPasswordPO) {
        ResetPasswordContext resetPasswordContext = userConverter.resetPasswordPO2ResetPasswordContext(resetPasswordPO);
        iUserService.resetPassword(resetPasswordContext);
        return R.success();
    }

    @ApiOperation(
            value = "用户在线修改密码",
            notes = "该接口提供了用户在线修改密码的功能",
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @PostMapping("password/change")
    public R changePassword(@Validated @RequestBody ChangePasswordPO changePasswordPO) {
        ChangePasswordContext changePasswordContext = userConverter.changePasswordPO2ChangePasswordContext(changePasswordPO);
        changePasswordContext.setUserId(StpUtil.getLoginIdAsLong());
        
        iUserService.changePassword(changePasswordContext);
        return R.success();
    }

    @ApiOperation(
            value = "查询登录用户的基本信息",
            notes = "该接口提供了查询登录用户的基本信息的功能",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @GetMapping("/")
    public R<UserInfoVO> info() {
        UserInfoVO userInfoVO = iUserService.info(StpUtil.getLoginIdAsLong());
        return R.data(userInfoVO);
    }
    
    /**
     * 获取用户相关存储信息接口
     * @return
     */
    @GetMapping("storage-size")
    public R<UserStorageSizeVO> userStorageSize(){
        UserStorageSizeVO userStorageVO = userStorageService.getUserStorage();
        return R.data(userStorageVO);
    }
    
    @GetMapping("/updateUserStorageSize")
    public R updateUserStorage(@RequestParam("businessSize") BigDecimal businessSize, @RequestParam("duration") Integer duration){
        userStorageService.updateUserStorageSize(businessSize, duration);
        return R.success();
    }
    
    @GetMapping("/addUserStorageUsed")
    public Object addUserStorageUsed(@RequestParam("userId") Long userId,
                                   @RequestParam(value = "fileSizeDesc", required = false) String fileSizeDesc,
                                @RequestParam("folderFlag") Integer folderFlag){
        Boolean isSuccess = userStorageService.addUserStorageUsed(userId, fileSizeDesc, folderFlag);
        return String.valueOf(isSuccess);
    }
    
    @GetMapping("isFull")
    public Object isFull(@RequestParam("userId") Long userId,
                       @RequestParam(value = "fileSizeDesc", required = false) String fileSizeDesc,
                       @RequestParam("folderFlag") Integer folderFlag){
        Boolean isSuccess = userStorageService.isFull(userId, fileSizeDesc, folderFlag);
        return String.valueOf(isSuccess);
    }
    
    @PostMapping("substracrStorageUsed")
    public void substracrStorageUsed(@RequestParam("userId") Long userId, @RequestBody() List<RPanUserFile> reconds){
        userStorageService.substractUserStorageUsed(userId,reconds);
    }
    
    @GetMapping("getUserInfoById")
    public RPanUser getUserInfo(@RequestParam("userId") Long userId){
        RPanUser rPanUser = iUserService.getById(userId);
        return rPanUser;
    }
}
